package com.tcs.tsrm.birch;

import java.util.ArrayList;
import java.util.HashMap;

import edu.gatech.gtisc.jbirch.cftree.CFTree;

public class JBirch {

	public static HashMap<Integer, Integer> originalToNonTrivial = new HashMap<Integer, Integer>();

	public ArrayList<ArrayList<Integer>> executeJBirch(
			ArrayList<double[]> nonTrivialMatrix, double coinRadius, int B) {
		int maxNodeEntries = B;
		double distThreshold = coinRadius;
		int distFunction = CFTree.D0_DIST;
		boolean applyMergingRefinement = true;
		int memoryLimit = 500;
		int memoryLimitPeriodicCheck = 10000; // verify memory usage after every
		// 10000 inserted instances

		// This initializes the tree
		CFTree birchTree = new CFTree(maxNodeEntries, distThreshold,
				distFunction, applyMergingRefinement);

		// comment the following three lines, if you do not want auto rebuild
		// based on memory usage constraints
		// if auto-rebuild is not active, you need to set distThreshold by hand
		birchTree.setAutomaticRebuild(false);
		birchTree.setMemoryLimitMB(memoryLimit);
		birchTree.setPeriodicMemLimitCheck(memoryLimitPeriodicCheck);// verify
		// memory
		// usage
		// after
		// every
		// memoryLimitPeriodicCheck

		// Read one instance at a time from the dataset
		// Dataset format: each line contain a set of value v1 v2 v3...
		// separated by spaces
		for (double[] point : nonTrivialMatrix) {
			int originalIndex = (int) point[1];
			int nonTrivialIndex = (int) point[0];
			originalToNonTrivial.put(originalIndex, nonTrivialIndex);
			double[] x = new double[point.length - 2];
			for (int i = 0; i < x.length; i++) {
				x[i] = point[i + 2];
				}
			boolean inserted = birchTree.insertEntry(x, (int) point[1]);
			if (!inserted) {
				System.err.println("ERROR: NOT INSERTED!");
				System.exit(1);
			}
		}
		birchTree.finishedInsertingData();

		return birchTree.getSubclusterMembers();
	}

}
